﻿#region CREDIT & LICENSE
/*******************************************
 * CREDIT: 
 * http://www.ROMPROS.com 
 * Tremendously helpful website, also would
 * like to give special thanks to:
 * 
 * Roverser - for the great effort on a c repository 
 * that most of this was ported from. http://code.google.com/p/rombot/
 * 
 * ROMeo - for the great amount of information shared
 * all across the rompros site. http://www.rompros.com/member.php?u=1901
 * 
 * 
 * LICENSE:
 *  
 * RomAPI is c# library is used to communicate directly with
 * the Runes Of Magic game client. 
 * 
 * Copyright (C) 2010  digitalxarts@gmail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 *******************************************/
#endregion#endregion
using System;
using System.Collections.Generic;
using System.Text;
//to support dynamically printing properties (toString Method)
using System.Reflection;
namespace RomAPI.Objects
{
    /// <summary>
    /// 
    /// </summary>
    public class RomObject : Object
    {
        /// <summary>
        /// Reference to the client that the object exists in.
        /// we need this to support multiple clients.
        /// </summary>
        public RomClient Client;
        /// <summary>
        /// All structures have a base pointer, 
        /// this is the address of that base pointer
        /// </summary>
        public uint BasePointer { get; set; }
        /// <summary>
        /// This is the address of what the base pointer
        /// is pointing to.
        /// </summary>
        public uint BaseAddress { get; set; }
        /// <summary>
        /// Constructor - must pass reference to client.
        /// </summary>
        /// <param name="client">client the object is being created for</param>
        /// <param name="baseAddress">base address (pointer) of this object</param>
        public RomObject(RomClient client, uint basePointer)
            : base()
        {
            //intialization 
            Client = client;
            BasePointer = basePointer;
            //re-assigns the BaseAddress of the BasePointer.
            Refresh();
        }
        /// <summary>
        /// This function allows you to re-assign the BaseAddress of this
        /// object based on the BasePointer. This makes it much easier
        /// to track changes on objects that might be moving to parts in memory.
        /// </summary>
        public void Refresh()
        {
            BaseAddress = GetPointerAddress(BasePointer);
        }
        protected uint GetPointerAddress(uint basePointer)
        {
            uint pointerAddress = 0;
            try
            {
                pointerAddress = Client.Memory.ReadUInt(basePointer);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return pointerAddress;
        }
        /// <summary>
        /// This function is used to read in bytes and turn it into a string
        /// </summary>
        /// <param name="offset">the offset of the property</param>
        /// <param name="size">the size of the string</param>
        /// <returns>the captured string</returns>
        protected string GetStringField(uint offset, int size)
        {
            string field = "";
            try
            {
                uint pointer = GetPointerAddress(BaseAddress + offset);
                field = Client.Memory.ReadASCIIString(pointer, size);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return field;
        }
        /// <summary>
        /// This function is used to get a simple value of a pointer
        /// </summary>
        /// <param name="size">the size of the string</param>
        /// <returns>the captured object</returns>
        protected T GetPointerField<T>(uint offset)
        {
            var field = default(T);
            try
            {
                uint pointer = GetPointerAddress(BaseAddress + offset);
                field = (T)Client.Memory.ReadObject(pointer, typeof(T));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return field;
        }
        /// <summary>
        /// This function is used to get a simple value of an address
        /// </summary>
        /// <param name="size">the size of the string</param>
        /// <returns>the captured object</returns>
        protected T GetField<T>(uint offset)
        {
            var field = default(T);
            try
            {
                field = (T)Client.Memory.ReadObject(BaseAddress + offset, typeof(T));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                //RomClientManager.Refresh();
            }
            return field;
        }
        /// <summary>
        /// This function is used to set a simple value of an address 
        /// NOTE: NOT TESTED YET. CURRENLY ONLY TESTING READING.
        /// </summary>
        /// <param name="size">the size of the string</param>
        /// <returns>the captured object</returns>
        protected void SetField<T>(uint offset, object value)
        {
            try
            {
                uint movement = GetPointerAddress(BaseAddress + offset);
                Client.Memory.WriteObject(BaseAddress + offset, value, typeof(T));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}
